"""单个技术指标分析器模块.

实现各个技术指标的看多/看空/中性判断逻辑。
"""

from __future__ import annotations

from typing import Any, Dict, Optional

import numpy as np
import pandas as pd

from .thresholds import IndicatorThresholds
from .types import SignalDirection, SignalResult, SignalStrength
from .utils import calculate_confidence

class SingleIndicatorAnalyzer:
    """单个技术指标分析器.
    
    实现各个技术指标的看多/看空/中性判断逻辑。
    """
    
    def __init__(self, thresholds: IndicatorThresholds):
        """初始化分析器.
        
        Parameters
        ----------
        thresholds : IndicatorThresholds
            阈值配置对象
        """
        self.thresholds = thresholds
    
    def analyze_rsi(self, rsi_value: float) -> SignalResult:
        """分析RSI指标.
        
        RSI是动量振荡器，范围0-100。
        - 看多：RSI < 30（超卖）
        - 看空：RSI > 70（超买）
        - 中性：30 ≤ RSI ≤ 70
        
        Parameters
        ----------
        rsi_value : float
            RSI指标值
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(rsi_value) or np.isnan(rsi_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=rsi_value,
                threshold_info={"oversold": self.thresholds.rsi_oversold, "overbought": self.thresholds.rsi_overbought, "reason": "值缺失"},
            )
        
        if rsi_value < self.thresholds.rsi_oversold:
            confidence, strength = calculate_confidence(
                rsi_value, self.thresholds.rsi_oversold, self.thresholds.rsi_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=rsi_value,
                threshold_info={"oversold": self.thresholds.rsi_oversold, "overbought": self.thresholds.rsi_overbought},
            )
        elif rsi_value > self.thresholds.rsi_overbought:
            confidence, strength = calculate_confidence(
                rsi_value, self.thresholds.rsi_oversold, self.thresholds.rsi_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=rsi_value,
                threshold_info={"oversold": self.thresholds.rsi_oversold, "overbought": self.thresholds.rsi_overbought},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=rsi_value,
                threshold_info={"oversold": self.thresholds.rsi_oversold, "overbought": self.thresholds.rsi_overbought},
            )
    
    def analyze_cmo(self, cmo_value: float) -> SignalResult:
        """分析CMO指标.
        
        CMO是动量振荡器，范围-100到+100。
        - 看多：CMO < -50
        - 看空：CMO > 50
        - 中性：-50 ≤ CMO ≤ 50
        
        Parameters
        ----------
        cmo_value : float
            CMO指标值
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(cmo_value) or np.isnan(cmo_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=cmo_value,
                threshold_info={"oversold": self.thresholds.cmo_oversold, "overbought": self.thresholds.cmo_overbought, "reason": "值缺失"},
            )
        
        if cmo_value < self.thresholds.cmo_oversold:
            confidence, strength = calculate_confidence(
                cmo_value, self.thresholds.cmo_oversold, self.thresholds.cmo_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=cmo_value,
                threshold_info={"oversold": self.thresholds.cmo_oversold, "overbought": self.thresholds.cmo_overbought},
            )
        elif cmo_value > self.thresholds.cmo_overbought:
            confidence, strength = calculate_confidence(
                cmo_value, self.thresholds.cmo_oversold, self.thresholds.cmo_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=cmo_value,
                threshold_info={"oversold": self.thresholds.cmo_oversold, "overbought": self.thresholds.cmo_overbought},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=cmo_value,
                threshold_info={"oversold": self.thresholds.cmo_oversold, "overbought": self.thresholds.cmo_overbought},
            )
    
    def analyze_kdj(
        self,
        k: float,
        d: float,
        j: Optional[float] = None,
        prev_k: Optional[float] = None,
        prev_d: Optional[float] = None,
    ) -> SignalResult:
        """分析KDJ指标.
        
        KDJ是随机振荡器，范围0-100。
        - 看多：K < 20 且 D < 20（超卖），或K上穿D（金叉）
        - 看空：K > 80 且 D > 80（超买），或K下穿D（死叉）
        - 中性：其他情况
        
        Parameters
        ----------
        k : float
            K值
        d : float
            D值
        j : Optional[float], optional
            J值（可选）
        prev_k : Optional[float], optional
            前一个K值（用于判断金叉死叉）
        prev_d : Optional[float], optional
            前一个D值（用于判断金叉死叉）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(k) or pd.isna(d) or np.isnan(k) or np.isnan(d):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value={"k": k, "d": d, "j": j},
                threshold_info={"oversold": self.thresholds.kdj_oversold, "overbought": self.thresholds.kdj_overbought, "reason": "值缺失"},
            )
        
        # 判断金叉死叉
        golden_cross = False
        death_cross = False
        if prev_k is not None and prev_d is not None and not (pd.isna(prev_k) or pd.isna(prev_d)):
            if prev_k < prev_d and k > d:  # 金叉：K从下方穿越D
                golden_cross = True
            elif prev_k > prev_d and k < d:  # 死叉：K从上方穿越D
                death_cross = True
        
        # 判断超买超卖
        oversold = k < self.thresholds.kdj_oversold and d < self.thresholds.kdj_oversold
        overbought = k > self.thresholds.kdj_overbought and d > self.thresholds.kdj_overbought
        
        if oversold or golden_cross:
            # 看多信号
            if oversold and golden_cross:
                confidence = 0.8
                strength = SignalStrength.STRONG
            elif oversold:
                confidence, strength = calculate_confidence(
                    min(k, d), self.thresholds.kdj_oversold, self.thresholds.kdj_overbought, is_oversold=True
                )
            else:  # golden_cross
                confidence = 0.6
                strength = SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value={"k": k, "d": d, "j": j},
                threshold_info={
                    "oversold": self.thresholds.kdj_oversold,
                    "overbought": self.thresholds.kdj_overbought,
                    "golden_cross": golden_cross,
                    "oversold_condition": oversold,
                },
            )
        elif overbought or death_cross:
            # 看空信号
            if overbought and death_cross:
                confidence = 0.8
                strength = SignalStrength.STRONG
            elif overbought:
                confidence, strength = calculate_confidence(
                    max(k, d), self.thresholds.kdj_oversold, self.thresholds.kdj_overbought, is_oversold=True
                )
            else:  # death_cross
                confidence = 0.6
                strength = SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value={"k": k, "d": d, "j": j},
                threshold_info={
                    "oversold": self.thresholds.kdj_oversold,
                    "overbought": self.thresholds.kdj_overbought,
                    "death_cross": death_cross,
                    "overbought_condition": overbought,
                },
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value={"k": k, "d": d, "j": j},
                threshold_info={"oversold": self.thresholds.kdj_oversold, "overbought": self.thresholds.kdj_overbought},
            )
    
    def analyze_williams_r(self, wr_value: float) -> SignalResult:
        """分析Williams %R指标.
        
        Williams %R是动量振荡器，范围-100到0。
        - 看多：Williams %R < -80（超卖）
        - 看空：Williams %R > -20（超买）
        - 中性：-80 ≤ Williams %R ≤ -20
        
        Parameters
        ----------
        wr_value : float
            Williams %R指标值
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(wr_value) or np.isnan(wr_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=wr_value,
                threshold_info={"oversold": self.thresholds.williams_r_oversold, "overbought": self.thresholds.williams_r_overbought, "reason": "值缺失"},
            )
        
        if wr_value < self.thresholds.williams_r_oversold:
            confidence, strength = calculate_confidence(
                wr_value, self.thresholds.williams_r_oversold, self.thresholds.williams_r_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=wr_value,
                threshold_info={"oversold": self.thresholds.williams_r_oversold, "overbought": self.thresholds.williams_r_overbought},
            )
        elif wr_value > self.thresholds.williams_r_overbought:
            confidence, strength = calculate_confidence(
                wr_value, self.thresholds.williams_r_oversold, self.thresholds.williams_r_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=wr_value,
                threshold_info={"oversold": self.thresholds.williams_r_oversold, "overbought": self.thresholds.williams_r_overbought},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=wr_value,
                threshold_info={"oversold": self.thresholds.williams_r_oversold, "overbought": self.thresholds.williams_r_overbought},
            )
    
    def analyze_cci(self, cci_value: float) -> SignalResult:
        """分析CCI指标.
        
        CCI衡量价格偏离统计平均值的程度，用于识别超买超卖。
        - 看多：CCI < -100
        - 看空：CCI > 100
        - 中性：-100 ≤ CCI ≤ 100
        
        Parameters
        ----------
        cci_value : float
            CCI指标值
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(cci_value) or np.isnan(cci_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=cci_value,
                threshold_info={"oversold": self.thresholds.cci_oversold, "overbought": self.thresholds.cci_overbought, "reason": "值缺失"},
            )
        
        if cci_value < self.thresholds.cci_oversold:
            confidence, strength = calculate_confidence(
                cci_value, self.thresholds.cci_oversold, self.thresholds.cci_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=cci_value,
                threshold_info={"oversold": self.thresholds.cci_oversold, "overbought": self.thresholds.cci_overbought},
            )
        elif cci_value > self.thresholds.cci_overbought:
            confidence, strength = calculate_confidence(
                cci_value, self.thresholds.cci_oversold, self.thresholds.cci_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=cci_value,
                threshold_info={"oversold": self.thresholds.cci_oversold, "overbought": self.thresholds.cci_overbought},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=cci_value,
                threshold_info={"oversold": self.thresholds.cci_oversold, "overbought": self.thresholds.cci_overbought},
            )
    
    def analyze_mfi(self, mfi_value: float) -> SignalResult:
        """分析MFI指标.
        
        MFI是结合价格和成交量的动量指标，类似于RSI但考虑了成交量因素，范围0-100。
        - 看多：MFI < 20（超卖）
        - 看空：MFI > 80（超买）
        - 中性：20 ≤ MFI ≤ 80
        
        Parameters
        ----------
        mfi_value : float
            MFI指标值
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(mfi_value) or np.isnan(mfi_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=mfi_value,
                threshold_info={"oversold": self.thresholds.mfi_oversold, "overbought": self.thresholds.mfi_overbought, "reason": "值缺失"},
            )
        
        if mfi_value < self.thresholds.mfi_oversold:
            confidence, strength = calculate_confidence(
                mfi_value, self.thresholds.mfi_oversold, self.thresholds.mfi_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=mfi_value,
                threshold_info={"oversold": self.thresholds.mfi_oversold, "overbought": self.thresholds.mfi_overbought},
            )
        elif mfi_value > self.thresholds.mfi_overbought:
            confidence, strength = calculate_confidence(
                mfi_value, self.thresholds.mfi_oversold, self.thresholds.mfi_overbought, is_oversold=True
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=mfi_value,
                threshold_info={"oversold": self.thresholds.mfi_oversold, "overbought": self.thresholds.mfi_overbought},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=mfi_value,
                threshold_info={"oversold": self.thresholds.mfi_oversold, "overbought": self.thresholds.mfi_overbought},
            )
    
    def analyze_macd(
        self,
        macd_dif: float,
        macd_dea: float,
        macd_hist: float,
        prev_macd_dif: Optional[float] = None,
        prev_macd_dea: Optional[float] = None,
        prev_macd_hist: Optional[float] = None,
    ) -> SignalResult:
        """分析MACD指标.
        
        MACD是趋势跟踪动量指标，通过快慢EMA的差值来判断趋势变化。
        - 看多：macd_dif > macd_dea（金叉）且 macd_hist > 0 且向上
        - 看空：macd_dif < macd_dea（死叉）且 macd_hist < 0 且向下
        - 中性：macd_dif ≈ macd_dea 或 macd_hist ≈ 0
        
        Parameters
        ----------
        macd_dif : float
            MACD DIF值
        macd_dea : float
            MACD DEA值
        macd_hist : float
            MACD柱状图值
        prev_macd_dif : Optional[float], optional
            前一个DIF值（用于判断趋势）
        prev_macd_dea : Optional[float], optional
            前一个DEA值（用于判断趋势）
        prev_macd_hist : Optional[float], optional
            前一个HIST值（用于判断柱状图趋势）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(macd_dif) or pd.isna(macd_dea) or pd.isna(macd_hist) or np.isnan(macd_dif) or np.isnan(macd_dea) or np.isnan(macd_hist):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value={"dif": macd_dif, "dea": macd_dea, "hist": macd_hist},
                threshold_info={"reason": "值缺失"},
            )
        
        # 判断金叉死叉
        golden_cross = False
        death_cross = False
        if prev_macd_dif is not None and prev_macd_dea is not None and not (pd.isna(prev_macd_dif) or pd.isna(prev_macd_dea)):
            if prev_macd_dif < prev_macd_dea and macd_dif > macd_dea:  # 金叉
                golden_cross = True
            elif prev_macd_dif > prev_macd_dea and macd_dif < macd_dea:  # 死叉
                death_cross = True
        
        # 判断柱状图趋势
        hist_rising = False
        hist_falling = False
        if prev_macd_hist is not None and not pd.isna(prev_macd_hist):
            if macd_hist > prev_macd_hist and macd_hist > 0:
                hist_rising = True
            elif macd_hist < prev_macd_hist and macd_hist < 0:
                hist_falling = True
        
        # 综合判断
        if (macd_dif > macd_dea and macd_hist > 0) or golden_cross:
            # 看多信号
            if golden_cross and macd_hist > 0:
                confidence = 0.8
                strength = SignalStrength.STRONG
            elif macd_dif > macd_dea and macd_hist > 0 and hist_rising:
                confidence = 0.7
                strength = SignalStrength.MODERATE
            else:
                confidence = 0.6
                strength = SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value={"dif": macd_dif, "dea": macd_dea, "hist": macd_hist},
                threshold_info={"golden_cross": golden_cross, "hist_rising": hist_rising},
            )
        elif (macd_dif < macd_dea and macd_hist < 0) or death_cross:
            # 看空信号
            if death_cross and macd_hist < 0:
                confidence = 0.8
                strength = SignalStrength.STRONG
            elif macd_dif < macd_dea and macd_hist < 0 and hist_falling:
                confidence = 0.7
                strength = SignalStrength.MODERATE
            else:
                confidence = 0.6
                strength = SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value={"dif": macd_dif, "dea": macd_dea, "hist": macd_hist},
                threshold_info={"death_cross": death_cross, "hist_falling": hist_falling},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value={"dif": macd_dif, "dea": macd_dea, "hist": macd_hist},
                threshold_info={},
            )
    
    def analyze_adx(self, adx: float, plus_di: float, minus_di: float) -> SignalResult:
        """分析ADX指标.
        
        ADX衡量趋势强度，+DI和-DI分别表示上升和下降趋势的强度。
        - 看多：ADX > 25（趋势强）且 +DI > -DI
        - 看空：ADX > 25（趋势强）且 +DI < -DI
        - 中性：ADX < 25（趋势弱，震荡）
        
        Parameters
        ----------
        adx : float
            ADX值（趋势强度）
        plus_di : float
            +DI值（上升趋势强度）
        minus_di : float
            -DI值（下降趋势强度）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(adx) or pd.isna(plus_di) or pd.isna(minus_di) or np.isnan(adx) or np.isnan(plus_di) or np.isnan(minus_di):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value={"adx": adx, "plus_di": plus_di, "minus_di": minus_di},
                threshold_info={"strong_trend": self.thresholds.adx_strong_trend, "reason": "值缺失"},
            )
        
        if adx > self.thresholds.adx_strong_trend:
            # 强趋势
            if plus_di > minus_di:
                # 上升趋势
                confidence = min(0.8, 0.5 + (adx - self.thresholds.adx_strong_trend) / 50.0)
                strength = SignalStrength.STRONG if adx > 40 else SignalStrength.MODERATE
                return SignalResult(
                    direction=SignalDirection.BULLISH,
                    strength=strength,
                    confidence=confidence,
                    value={"adx": adx, "plus_di": plus_di, "minus_di": minus_di},
                    threshold_info={"strong_trend": self.thresholds.adx_strong_trend, "trend_direction": "up"},
                )
            else:
                # 下降趋势
                confidence = min(0.8, 0.5 + (adx - self.thresholds.adx_strong_trend) / 50.0)
                strength = SignalStrength.STRONG if adx > 40 else SignalStrength.MODERATE
                return SignalResult(
                    direction=SignalDirection.BEARISH,
                    strength=strength,
                    confidence=confidence,
                    value={"adx": adx, "plus_di": plus_di, "minus_di": minus_di},
                    threshold_info={"strong_trend": self.thresholds.adx_strong_trend, "trend_direction": "down"},
                )
        else:
            # 弱趋势（震荡）
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value={"adx": adx, "plus_di": plus_di, "minus_di": minus_di},
                threshold_info={"strong_trend": self.thresholds.adx_strong_trend, "trend_direction": "weak"},
            )
    
    def analyze_bollinger(self, bb_position: float, price: Optional[float] = None, bb_upper: Optional[float] = None, bb_lower: Optional[float] = None) -> SignalResult:
        """分析布林带指标.
        
        布林带由中轨（SMA）、上轨、下轨组成，用于判断价格是否偏离正常范围。
        - 看多：价格触及或跌破下轨（bb_position < 0.2）
        - 看空：价格触及或突破上轨（bb_position > 0.8）
        - 中性：价格在中轨附近（0.3 ≤ bb_position ≤ 0.7）
        
        Parameters
        ----------
        bb_position : float
            价格在布林带中的位置（0-1之间）
        price : Optional[float], optional
            当前价格（可选）
        bb_upper : Optional[float], optional
            布林带上轨（可选）
        bb_lower : Optional[float], optional
            布林带下轨（可选）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(bb_position) or np.isnan(bb_position):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value={"bb_position": bb_position, "price": price, "bb_upper": bb_upper, "bb_lower": bb_lower},
                threshold_info={"lower": self.thresholds.bollinger_lower, "upper": self.thresholds.bollinger_upper, "reason": "值缺失"},
            )
        
        if bb_position < self.thresholds.bollinger_lower:
            # 价格触及或跌破下轨，看多
            confidence, strength = calculate_confidence(
                bb_position, self.thresholds.bollinger_lower, self.thresholds.bollinger_upper, is_oversold=False
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value={"bb_position": bb_position, "price": price, "bb_upper": bb_upper, "bb_lower": bb_lower},
                threshold_info={"lower": self.thresholds.bollinger_lower, "upper": self.thresholds.bollinger_upper},
            )
        elif bb_position > self.thresholds.bollinger_upper:
            # 价格触及或突破上轨，看空
            confidence, strength = calculate_confidence(
                bb_position, self.thresholds.bollinger_lower, self.thresholds.bollinger_upper, is_oversold=False
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value={"bb_position": bb_position, "price": price, "bb_upper": bb_upper, "bb_lower": bb_lower},
                threshold_info={"lower": self.thresholds.bollinger_lower, "upper": self.thresholds.bollinger_upper},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value={"bb_position": bb_position, "price": price, "bb_upper": bb_upper, "bb_lower": bb_lower},
                threshold_info={"lower": self.thresholds.bollinger_lower, "upper": self.thresholds.bollinger_upper},
            )
    
    def analyze_price_percentile(self, percentile_value: float) -> SignalResult:
        """分析价格百分位排名.
        
        计算当前价格在过去N日价格区间中的百分位排名，反映价格相对位置。
        - 看多：percentile < 20（接近历史低位）
        - 看空：percentile > 80（接近历史高位）
        - 中性：20 ≤ percentile ≤ 80
        
        Parameters
        ----------
        percentile_value : float
            价格百分位排名（0-100）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(percentile_value) or np.isnan(percentile_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=percentile_value,
                threshold_info={"lower": self.thresholds.price_percentile_lower, "upper": self.thresholds.price_percentile_upper, "reason": "值缺失"},
            )
        
        if percentile_value < self.thresholds.price_percentile_lower:
            confidence, strength = calculate_confidence(
                percentile_value, self.thresholds.price_percentile_lower, self.thresholds.price_percentile_upper, is_oversold=False
            )
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=percentile_value,
                threshold_info={"lower": self.thresholds.price_percentile_lower, "upper": self.thresholds.price_percentile_upper},
            )
        elif percentile_value > self.thresholds.price_percentile_upper:
            confidence, strength = calculate_confidence(
                percentile_value, self.thresholds.price_percentile_lower, self.thresholds.price_percentile_upper, is_oversold=False
            )
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=percentile_value,
                threshold_info={"lower": self.thresholds.price_percentile_lower, "upper": self.thresholds.price_percentile_upper},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=percentile_value,
                threshold_info={"lower": self.thresholds.price_percentile_lower, "upper": self.thresholds.price_percentile_upper},
            )
    
    def analyze_vwap_bias(self, bias_value: float) -> SignalResult:
        """分析VWAP偏差.
        
        VWAP是成交量加权平均价，当前价格相对于VWAP的偏差反映价格是否偏离合理价值。
        - 看多：bias < -0.02（价格低于VWAP，可能反弹）
        - 看空：bias > 0.02（价格高于VWAP，可能回调）
        - 中性：-0.02 ≤ bias ≤ 0.02
        
        Parameters
        ----------
        bias_value : float
            VWAP偏差值（(price - vwap) / vwap）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(bias_value) or np.isnan(bias_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=bias_value,
                threshold_info={"lower": self.thresholds.vwap_bias_lower, "upper": self.thresholds.vwap_bias_upper, "reason": "值缺失"},
            )
        
        if bias_value < self.thresholds.vwap_bias_lower:
            # 价格低于VWAP，看多
            distance = abs(bias_value - self.thresholds.vwap_bias_lower)
            confidence = min(0.8, 0.5 + distance * 10)
            strength = SignalStrength.STRONG if distance > 0.03 else SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=bias_value,
                threshold_info={"lower": self.thresholds.vwap_bias_lower, "upper": self.thresholds.vwap_bias_upper},
            )
        elif bias_value > self.thresholds.vwap_bias_upper:
            # 价格高于VWAP，看空
            distance = abs(bias_value - self.thresholds.vwap_bias_upper)
            confidence = min(0.8, 0.5 + distance * 10)
            strength = SignalStrength.STRONG if distance > 0.03 else SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=bias_value,
                threshold_info={"lower": self.thresholds.vwap_bias_lower, "upper": self.thresholds.vwap_bias_upper},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=bias_value,
                threshold_info={"lower": self.thresholds.vwap_bias_lower, "upper": self.thresholds.vwap_bias_upper},
            )
    
    def analyze_ma_system(self, sma5: Optional[float] = None, sma10: Optional[float] = None, sma20: Optional[float] = None, ema5: Optional[float] = None, ema10: Optional[float] = None, ema20: Optional[float] = None, price: Optional[float] = None) -> SignalResult:
        """分析均线系统.
        
        均线系统通过多条均线的排列和价格与均线的关系判断趋势。
        - 看多：价格 > 均线 且 短期均线 > 长期均线（多头排列）
        - 看空：价格 < 均线 且 短期均线 < 长期均线（空头排列）
        - 中性：均线纠缠或价格在均线附近
        
        Parameters
        ----------
        sma5 : Optional[float], optional
            SMA5值
        sma10 : Optional[float], optional
            SMA10值
        sma20 : Optional[float], optional
            SMA20值
        ema5 : Optional[float], optional
            EMA5值
        ema10 : Optional[float], optional
            EMA10值
        ema20 : Optional[float], optional
            EMA20值
        price : Optional[float], optional
            当前价格
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        # 优先使用SMA，如果没有则使用EMA
        ma5 = sma5 if sma5 is not None and not pd.isna(sma5) else (ema5 if ema5 is not None and not pd.isna(ema5) else None)
        ma10 = sma10 if sma10 is not None and not pd.isna(sma10) else (ema10 if ema10 is not None and not pd.isna(ema10) else None)
        ma20 = sma20 if sma20 is not None and not pd.isna(sma20) else (ema20 if ema20 is not None and not pd.isna(ema20) else None)
        
        if ma5 is None or ma10 is None or ma20 is None or price is None:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value={"sma5": sma5, "sma10": sma10, "sma20": sma20, "ema5": ema5, "ema10": ema10, "ema20": ema20, "price": price},
                threshold_info={"reason": "值缺失"},
            )
        
        # 判断多头排列：价格 > MA5 > MA10 > MA20
        bullish_alignment = price > ma5 > ma10 > ma20
        # 判断空头排列：价格 < MA5 < MA10 < MA20
        bearish_alignment = price < ma5 < ma10 < ma20
        
        if bullish_alignment:
            # 多头排列，看多
            confidence = 0.7
            strength = SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value={"sma5": sma5, "sma10": sma10, "sma20": sma20, "ema5": ema5, "ema10": ema10, "ema20": ema20, "price": price},
                threshold_info={"alignment": "bullish"},
            )
        elif bearish_alignment:
            # 空头排列，看空
            confidence = 0.7
            strength = SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value={"sma5": sma5, "sma10": sma10, "sma20": sma20, "ema5": ema5, "ema10": ema10, "ema20": ema20, "price": price},
                threshold_info={"alignment": "bearish"},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value={"sma5": sma5, "sma10": sma10, "sma20": sma20, "ema5": ema5, "ema10": ema10, "ema20": ema20, "price": price},
                threshold_info={"alignment": "neutral"},
            )
    
    def analyze_trend_persistence(self, persistence_value: float) -> SignalResult:
        """分析趋势持续性.
        
        计算价格在移动平均线上方/下方的连续天数，反映趋势的持续性。
        - 看多：persistence > 0 且数值较大（连续多日在均线上方）
        - 看空：persistence < 0 且绝对值较大（连续多日在均线下方）
        - 中性：persistence ≈ 0（频繁穿越均线）
        
        Parameters
        ----------
        persistence_value : float
            趋势持续性值（正数表示上方，负数表示下方）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(persistence_value) or np.isnan(persistence_value):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value=persistence_value,
                threshold_info={"strong_bullish": self.thresholds.trend_persistence_strong_bullish, "strong_bearish": self.thresholds.trend_persistence_strong_bearish, "reason": "值缺失"},
            )
        
        if persistence_value > self.thresholds.trend_persistence_strong_bullish:
            # 强烈看多：连续多日在均线上方
            confidence = min(0.8, 0.5 + (persistence_value - self.thresholds.trend_persistence_strong_bullish) / 10.0)
            strength = SignalStrength.STRONG
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=persistence_value,
                threshold_info={"strong_bullish": self.thresholds.trend_persistence_strong_bullish, "strong_bearish": self.thresholds.trend_persistence_strong_bearish},
            )
        elif persistence_value < self.thresholds.trend_persistence_strong_bearish:
            # 强烈看空：连续多日在均线下方
            confidence = min(0.8, 0.5 + abs(persistence_value - self.thresholds.trend_persistence_strong_bearish) / 10.0)
            strength = SignalStrength.STRONG
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=persistence_value,
                threshold_info={"strong_bullish": self.thresholds.trend_persistence_strong_bullish, "strong_bearish": self.thresholds.trend_persistence_strong_bearish},
            )
        elif persistence_value > 0:
            # 轻微看多
            confidence = 0.4
            strength = SignalStrength.WEAK
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=persistence_value,
                threshold_info={"strong_bullish": self.thresholds.trend_persistence_strong_bullish, "strong_bearish": self.thresholds.trend_persistence_strong_bearish},
            )
        elif persistence_value < 0:
            # 轻微看空
            confidence = 0.4
            strength = SignalStrength.WEAK
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=persistence_value,
                threshold_info={"strong_bullish": self.thresholds.trend_persistence_strong_bullish, "strong_bearish": self.thresholds.trend_persistence_strong_bearish},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=persistence_value,
                threshold_info={"strong_bullish": self.thresholds.trend_persistence_strong_bullish, "strong_bearish": self.thresholds.trend_persistence_strong_bearish},
            )
    
    def analyze_obv(self, obv_ratio: float, obv_trend: Optional[float] = None) -> SignalResult:
        """分析OBV指标.
        
        OBV通过成交量变化预测价格变化，基于价涨量增、价跌量减的假设。
        - 看多：OBV上升且价格上升（价涨量增），或obv_ratio > 1.1
        - 看空：OBV下降且价格上升（价涨量缩，背离），或obv_ratio < 0.9
        - 中性：OBV与价格同步或obv_ratio ≈ 1
        
        Parameters
        ----------
        obv_ratio : float
            OBV比率（OBV / OBV均线）
        obv_trend : Optional[float], optional
            OBV趋势（OBV变化率，可选）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        if pd.isna(obv_ratio) or np.isnan(obv_ratio):
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.0,
                value={"obv_ratio": obv_ratio, "obv_trend": obv_trend},
                threshold_info={"lower": self.thresholds.obv_ratio_lower, "upper": self.thresholds.obv_ratio_upper, "reason": "值缺失"},
            )
        
        if obv_ratio > self.thresholds.obv_ratio_upper:
            # OBV高于均线，看多
            distance = obv_ratio - self.thresholds.obv_ratio_upper
            confidence = min(0.8, 0.5 + distance * 2)
            strength = SignalStrength.STRONG if distance > 0.2 else SignalStrength.MODERATE
            if obv_trend is not None and obv_trend > 0:
                # OBV上升趋势，增强信号
                confidence = min(0.9, confidence + 0.1)
                strength = SignalStrength.STRONG
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value={"obv_ratio": obv_ratio, "obv_trend": obv_trend},
                threshold_info={"lower": self.thresholds.obv_ratio_lower, "upper": self.thresholds.obv_ratio_upper},
            )
        elif obv_ratio < self.thresholds.obv_ratio_lower:
            # OBV低于均线，看空
            distance = self.thresholds.obv_ratio_lower - obv_ratio
            confidence = min(0.8, 0.5 + distance * 2)
            strength = SignalStrength.STRONG if distance > 0.2 else SignalStrength.MODERATE
            if obv_trend is not None and obv_trend < 0:
                # OBV下降趋势，增强信号
                confidence = min(0.9, confidence + 0.1)
                strength = SignalStrength.STRONG
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value={"obv_ratio": obv_ratio, "obv_trend": obv_trend},
                threshold_info={"lower": self.thresholds.obv_ratio_lower, "upper": self.thresholds.obv_ratio_upper},
            )
        else:
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value={"obv_ratio": obv_ratio, "obv_trend": obv_trend},
                threshold_info={"lower": self.thresholds.obv_ratio_lower, "upper": self.thresholds.obv_ratio_upper},
            )
    
    def analyze_candlestick_patterns(self, patterns_dict: Dict[str, int]) -> SignalResult:
        """分析K线形态.
        
        识别11种常见的K线形态，包括基础形态和高级形态。
        - 看多形态：锤子线、看涨吞没、晨星、刺透形态、三白兵
        - 看空形态：上吊线、看跌吞没、暮星、乌云盖顶、三只乌鸦
        - 中性形态：十字星（表示犹豫）
        
        Parameters
        ----------
        patterns_dict : Dict[str, int]
            K线形态字典，key为形态名称，value为0（未识别）或1（已识别）
            
        Returns
        -------
        SignalResult
            信号分析结果
        """
        # 看多形态
        bullish_patterns = [
            "pattern_hammer",
            "pattern_bullish_engulfing",
            "pattern_morning_star",
            "pattern_piercing",
            "pattern_three_white_soldiers",
        ]
        
        # 看空形态
        bearish_patterns = [
            "pattern_hanging_man",
            "pattern_bearish_engulfing",
            "pattern_evening_star",
            "pattern_dark_cloud",
            "pattern_three_black_crows",
        ]
        
        # 中性形态
        neutral_patterns = ["pattern_doji"]
        
        # 统计各类形态数量
        bullish_count = sum(patterns_dict.get(pattern, 0) for pattern in bullish_patterns)
        bearish_count = sum(patterns_dict.get(pattern, 0) for pattern in bearish_patterns)
        neutral_count = sum(patterns_dict.get(pattern, 0) for pattern in neutral_patterns)
        
        if bullish_count > bearish_count and bullish_count > 0:
            # 看多形态占优
            confidence = min(0.8, 0.5 + bullish_count * 0.1)
            strength = SignalStrength.STRONG if bullish_count >= 2 else SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BULLISH,
                strength=strength,
                confidence=confidence,
                value=patterns_dict,
                threshold_info={"bullish_count": bullish_count, "bearish_count": bearish_count, "neutral_count": neutral_count},
            )
        elif bearish_count > bullish_count and bearish_count > 0:
            # 看空形态占优
            confidence = min(0.8, 0.5 + bearish_count * 0.1)
            strength = SignalStrength.STRONG if bearish_count >= 2 else SignalStrength.MODERATE
            return SignalResult(
                direction=SignalDirection.BEARISH,
                strength=strength,
                confidence=confidence,
                value=patterns_dict,
                threshold_info={"bullish_count": bullish_count, "bearish_count": bearish_count, "neutral_count": neutral_count},
            )
        else:
            # 中性或形态冲突
            return SignalResult(
                direction=SignalDirection.NEUTRAL,
                strength=SignalStrength.WEAK,
                confidence=0.2,
                value=patterns_dict,
                threshold_info={"bullish_count": bullish_count, "bearish_count": bearish_count, "neutral_count": neutral_count},
            )

